import logging
from operator import and_, not_

from info import constants, db
from info.models import News, Comment, User, CommentLike
from . import news_blu
from info.utils.common import user_login_data
from flask import render_template, make_response, g, request, jsonify, redirect, current_app


# Todo 新闻详情页
@news_blu.route('/<int:news_id>.html')
@user_login_data
def news_detail(news_id):
    is_collected = False
    user = g.user
    # 查询新闻数据
    try:
        upnews = News.query.filter(News.status==0).order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS).all()
    except Exception as e:
        logging.error("Mysql数据库出错,错误原因%s"%e)
        return redirect("/500.html")
    try:
        news = News.query.filter(and_(News.id==news_id,News.status==0)).all()
    except Exception as e:
        logging.error("Mysql数据库异常%s"%e)
        return redirect("/500.html")
    # 校验报404错误
    if not news:
        logging.warning("页面未找到")
        return redirect("/404.html")
    news = news[0]
    # 获取作者
    author = User.query.filter(User.id==news.user_id).first()
    is_followed = False
    if user:
        if author in user.followed:
            is_followed = True
    # 进入详情页后要更新新闻的点击次数
    news.comments_count = news.comments.count()
    comments = news.comments.all()
    try:
        for comment in comments:
            if comment.parent_id:
                parent = Comment.query.filter(Comment.id==comment.parent_id).all()
                if parent:
                    comment.parent = parent[0]
                    p_user = User.query.filter(User.id==comment.parent.user_id).all()
                    if p_user:
                        comment.parent.user = p_user[0]
            comment.user = User.query.filter(User.id==comment.user_id).all()[0]
            if user:
                clike = CommentLike.query.filter(and_(CommentLike.comment_id==comment.id,CommentLike.user_id==user.id)).all()
                if clike:
                    comment.is_like = True
                else:
                    comment.is_like = False
    except Exception as e:
        logging.error("Mysql数据库异常%s" % e)
        return redirect("/500.html")
    # 返回数据
    if user:
        if news in user.collection_news:
            is_collected = True

    data = {
        "user":user,
        "news":news,
        "upnews":upnews,
        "comments":comments,
        "is_collected":is_collected,
        "is_followed":is_followed,
        "author":author
    }
    return make_response(render_template('news/detail.html',data=data),constants.PAGE_NET_TAG)

@news_blu.route("/news_collect", methods=['POST'])
@user_login_data
def news_collect():
    """新闻收藏"""
    user = g.user
    if not user:
        data = {
            "errno":constants.NO_ENTER_TAG,
        }
        return jsonify(data)
    # 获取参数
    news_id = request.json.get('news_id')
    action = request.json.get('action')
    # 判断参数
	# action在不在指定的两个值：'collect', 'cancel_collect'内
    if action not in ['collect','cancel_collect']:
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"动作错误"
        }
        return jsonify(data)
    news = News.query.get(news_id)
    # 查询新闻,并判断新闻是否存在
    if not news:
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"新闻不存在"
        }
        return jsonify(data)
    # 收藏/取消收藏
    if action == "cancel_collect":
        if news in user.collection_news:
            try:
                user.collection_news.remove(news)
                db.session.commit()
            except Exception as e:
                logging.error("Mysql出错,错误原因%s"%e)
                data = {
                    "errno":constants.SYSTEM_WRONE_TAG,
                    "errmsg":"系统出错"
                }
                return jsonify(data)
        data = {
            "errno":0
        }
        return jsonify(data)
    else:
        # 收藏
        if news not in user.collection_news:
            try:
                user.collection_news.append(news)
                db.session.commit()
            except Exception as e:
                logging.error("数据库出错,错误原因%s"%e)
                data = {
                    "errno":constants.SYSTEM_WRONE_TAG,
                    "error":"系统错误"
                }
                return jsonify(data)
        data = {
            "errno":constants.CORRECT_TAG
        }
        return jsonify(data)

# Todo 用户评论(新评论)(子评论)
@news_blu.route('/news_comment', methods=["POST"])
@user_login_data
def add_news_comment():
    """添加评论"""

    # 用户是否登陆
    user = g.user
    if not user:
        data = {
            "errno":constants.NO_ENTER_TAG,
        }
        return jsonify(data)
    # 获取参数
    news_id = request.json.get('news_id')
    content = request.json.get('comment')
    parent_id = request.json.get('parent_id',None)

    # 判断参数是否正确
    if not all([news_id,content]):
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"参数不正确"
        }
        return jsonify(data)

    try:
        int(news_id)
    except Exception as e:
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"参数错误"
        }
        return jsonify(data)
    # 查询新闻是否存在并校验
    try:
        news = News.query.filter(News.id==news_id).all()
        if not news:
            data = {
                "errno": constants.WRONG_INPUT_TAG,
                "errmsg": "没有该新闻"
            }
            return jsonify(data)
        else:
            news = news[0]
        # 初始化评论模型，保存数据
        leng = len(news.comments.all()) + 1
        if parent_id:
            p_comment = Comment.query.filter(Comment.id==parent_id).all()
            if p_comment:
                comment = Comment(parent_id=parent_id, news_id=news_id, content=content, user_id=user.id)
            else:
                data = {
                    "errno":constants.WRONG_INPUT_TAG,
                    "errmsg":"没有父评论"
                }
                return jsonify(data)
        else:
            comment = Comment(content=content,user_id=g.user.id,news_id=news.id)
    except Exception as e:
        logging.error("Mysql出错，错误原因%s" % e)
        data = {
            "errno": constants.SYSTEM_WRONE_TAG,
            "errmsg": "系统出错"
        }
        return jsonify(data)
    # 配置文件设置了自动提交,自动提交要在return返回结果以后才执行commit命令,如果有回复
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        logging.error("Mysql出错，错误原因%s"%e)
        data = {
            "errno":constants.SYSTEM_WRONE_TAG,
            "errmsg":"系统出错"
        }
        return jsonify(data)

    # 评论,先拿到回复评论id,在手动commit,否则无法获取回复评论内容
    data={
        "errno":constants.CORRECT_TAG,
        "data":comment.to_dict(),
        "leng":leng
    }
    # 返回响应
    return jsonify(data)

# 用户点赞
@news_blu.route('/comment_like', methods=["POST"])
@user_login_data
def comment_like():
    """
    评论点赞
    :return:
    """
    # 用户是否登陆
    if not g.user:
        data = {
            "errno":constants.NO_ENTER_TAG
        }
        return jsonify(data)
    # 取到请求参数
    comment_id = request.json.get("comment_id")
    action = request.json.get('action')
    # 判断参数
    if not all([action,comment_id]):
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"数据不完整"
        }
        return jsonify(data)
    if action not in ["add","remove"]:
        data = {
            "errno":constants.WRONG_INPUT_TAG,
            "errmsg":"操作不合法"
        }
        return jsonify(data)

    # 获取到要被点赞的评论模型
    try:
        comment = Comment.query.filter(Comment.id==comment_id).all()
        if not comment:
            data = {
                "error":constants.WRONG_INPUT_TAG,
                "errmsg":"该评论已被撤销"
            }
            return jsonify(data)
        comment = comment[0]
    except Exception as e:
        logging.error("Mysql出错,错误原因%s"%e)
        data = {
            "error":constants.SYSTEM_WRONE_TAG,
            "errmsg":"系统错误"
        }
        return jsonify(data)
    # action的状态,如果点赞,则查询后将用户id和评论id添加到数据库
            # 点赞评论
    try:
        if action == "add":
            commentlike = CommentLike.query.filter(and_(CommentLike.comment_id==comment.id,CommentLike.user_id==g.user.id)).all()
            if not commentlike:
                commentlike = CommentLike(user_id=g.user.id,comment_id=comment_id)
                db.session.add(commentlike)
                # 更新点赞次数
                comment.like_count+=1
                db.session.commit()
        # 取消点赞评论,查询数据库,如果以点在,则删除点赞信息
        else:
            commentlike = CommentLike.query.filter(and_(CommentLike.comment_id==comment.id,CommentLike.user_id==g.user.id)).all()
            if commentlike:
                commentlike = commentlike[0]
                db.session.delete(commentlike)
                # 更新点赞次数
                comment.like_count-=1
                db.session.commit()
    except Exception as e:
        db.session.rollback()
        logging.error("Mysql出错,出错原因为%s"%e)
        data = {
            "errno":constants.SYSTEM_WRONE_TAG,
            "errmsg":"系统出错"
        }
        return jsonify(data)
    data = {
        "errno":constants.CORRECT_TAG,
        "comment_id":comment.id,
        "like_count":comment.like_count
    }
    return jsonify(data)



@news_blu.route('/followed_user', methods=["POST"])
@user_login_data
def followed_user():
    """关注或者取消关注用户"""

    # 获取自己登录信息
    user = g.user
    if not user:
        return jsonify(errno=constants.NO_ENTER_TAG, errmsg="未登录")

    # 获取参数
    user_id = request.json.get("user_id")
    action = request.json.get("action")

    # 判断参数
    if not all([user_id, action]):
        return jsonify(errno=constants.WRONG_INPUT_TAG, errmsg="参数错误")

    if action not in ("follow", "unfollow"):
        return jsonify(errno=constants.WRONG_INPUT_TAG, errmsg="参数错误")

    # 获取要被关注的用户
    try:
        other = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=constants.SYSTEM_WRONE_TAG, errmsg="数据查询错误")

    if not other:
        return jsonify(errno=constants.WRONG_INPUT_TAG, errmsg="未查询到数据")

    if other.id == user.id:
        return jsonify(errno=constants.WRONG_INPUT_TAG, errmsg="请勿关注自己")

    # 根据要执行的操作去修改对应的数据
    if action == "follow":
        if other not in user.followed:
            # 当前用户的关注列表添加一个值
            user.followed.append(other)
            db.session.commit()
    else:
        # 取消关注
        if other in user.followed:
            user.followed.remove(other)
            db.session.commit()

    return jsonify(errno=constants.CORRECT_TAG, errmsg="操作成功")



